package com.atguigu.gmall.order.listener;
import com.atguigu.gmall.order.entity.OrderDetail;
import com.atguigu.gmall.order.service.OrderDetailService;
import com.google.common.collect.Lists;
import java.math.BigDecimal;
import java.util.Date;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.atguigu.gmall.common.config.mq.MqService;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.mq.ware.WareStockMsg;
import com.atguigu.gmall.order.biz.OrderBizService;
import com.atguigu.gmall.order.entity.OrderInfo;
import com.atguigu.gmall.order.entity.PaymentInfo;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.atguigu.gmall.order.service.PaymentInfoService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderPayedListener {

    @Autowired
    MqService mqService;
    @Autowired
    OrderBizService orderBizService;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    PaymentInfoService paymentInfoService;
    @Autowired
    OrderDetailService orderDetailService;

    //监听支付成功的订单
    @RabbitListener(queues = MqConst.ORDER_PAYED_QUEUE)
    public void listen(Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        String json = new String(message.getBody());//支付宝传来的消息内容
        try {
            log.info("收到需要修改为 支付成功 的订单消息：{}",json);
            Map<String, String> content = JSON.parseObject(json, new TypeReference<Map<String, String>>() {
            });//复杂类型转换 TypeReference
            //1 订单的唯一交易号
            String out_trade_no = content.get("out_trade_no");//"out_trade_no": "ATGUIGU-1672740360775-3"
            //2 用户id
            String[] split = out_trade_no.split("-");
            Long userId = Long.parseLong(split[split.length - 1]);
            //3 根据userId和交易号修改订单状态为已支付状态
            orderBizService.payedOrder(out_trade_no,userId);

            //保存回调信息 操作数据库 payment_info
            PaymentInfo paymentInfo = preparePaymentInfo(json, content, out_trade_no, userId);
            paymentInfoService.save(paymentInfo);

            //todo: 实现支付后锁定库存。解决：发送消息通知库存系统扣减库存
            WareStockMsg msg = prepareWareStockMsg(out_trade_no,userId);
            mqService.send(msg, MqConst.WARE_STOCK_EXCHANGE, MqConst.WARE_STOCK_RK);//给queue.ware.stock 发送消息==>通知库存系统扣减库存

            //收到消息，回复ok
            channel.basicAck(deliveryTag, false);
        }catch (Exception e){
            mqService.retry(channel, deliveryTag, json, 5);
        }
    }

    //准备要发送的消息
    private WareStockMsg prepareWareStockMsg(String out_trade_no, Long userId) {
        //获取订单
        OrderInfo orderInfo = orderInfoService.lambdaQuery()
                .eq(OrderInfo::getUserId, userId)
                .eq(OrderInfo::getOutTradeNo, out_trade_no)
                .one();
        //订单基本信息
        WareStockMsg msg = new WareStockMsg();
        msg.setOrderId(orderInfo.getId());
        msg.setUserId(orderInfo.getUserId());
        msg.setConsignee(orderInfo.getConsignee());
        msg.setConsigneeTel(orderInfo.getConsigneeTel());
        msg.setOrderComment(orderInfo.getOrderComment());
        msg.setOrderBody(orderInfo.getTradeBody());
        msg.setDeliveryAddress(orderInfo.getDeliveryAddress());
        msg.setPaymentWay("2");

        //msg.setWareId(0L);
        //订单明细
        List<OrderDetail> detailList = orderDetailService.lambdaQuery()
                .eq(OrderDetail::getOrderId, orderInfo.getId())
                .eq(OrderDetail::getUserId, orderInfo.getUserId())
                .list();
        List<WareStockMsg.Sku> skuList = detailList.stream()
                .map(item -> {
                    WareStockMsg.Sku sku = new WareStockMsg.Sku();
                    sku.setSkuId(item.getSkuId());
                    sku.setSkuNum(item.getSkuNum());
                    sku.setSkuName(item.getSkuName());
                    return sku;
                })
                .collect(Collectors.toList());
        msg.setDetails(skuList);

        return msg;
    }

    //保存回调信息 操作数据库 payment_info
    private PaymentInfo preparePaymentInfo(String json, Map<String, String> content, String out_trade_no, long userId) {
        OrderInfo orderInfo = orderInfoService.lambdaQuery()
                .eq(OrderInfo::getUserId, userId)
                .eq(OrderInfo::getOutTradeNo, out_trade_no)
                .one();
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setUserId(userId);
        paymentInfo.setOutTradeNo(out_trade_no);
        paymentInfo.setOrderId(orderInfo.getId());
        paymentInfo.setPaymentType(orderInfo.getPaymentWay());

        String trade_no = content.get("trade_no");
        paymentInfo.setTradeNo(trade_no);

        String total_amount = content.get("total_amount");
        paymentInfo.setTotalAmount(new BigDecimal(total_amount));

        String subject = content.get("subject");
        paymentInfo.setSubject(subject);

        paymentInfo.setPaymentStatus(content.get("trade_status"));
        paymentInfo.setCreateTime(new Date());
        paymentInfo.setCallbackTime(new Date());
        paymentInfo.setCallbackContent(json);
        return paymentInfo;
    }
}
